package model.geneticAlgorithm.organismBreedingStrategies;

import java.util.ArrayList;
import java.util.Random;

import model.organism.Organism;
import model.organism.SimpleStringOrganism;

public class CrossoverOrganismBreedingStrategy implements OrganismBreedingStrategy
{

	Random randomGenerator = new Random(System.currentTimeMillis());
	
	@Override
	public Organism breedOrganism(Organism parent1, Organism parent2, float mutationRate)
	{
		if(parent1 == null || parent2 == null)
		{
			return null;
		}
		
		int crossoverPoint = Math.abs(randomGenerator.nextInt()%SimpleStringOrganism.getNumberOfChromosones());
		ArrayList<Character> childGenes = new ArrayList<Character>(SimpleStringOrganism.getNumberOfChromosones());
		childGenes.addAll(getGenesToCrossoverPoint((SimpleStringOrganism)parent1, crossoverPoint));
		childGenes.addAll(getGenesFromCrossoverPointToEnd((SimpleStringOrganism)parent2, crossoverPoint));
		SimpleStringOrganism organism = new SimpleStringOrganism();
		organism.setChromosones(childGenes);
		mutateOrganism(organism, mutationRate);
		return organism;
	}
	
	public ArrayList<Character> getGenesToCrossoverPoint(SimpleStringOrganism organism, int crossoverPoint)
	{
		ArrayList<Character> genesToReturn = new ArrayList<Character>(crossoverPoint);
		for(int i = 0; i < crossoverPoint; i++)
		{
			genesToReturn.add(i, organism.getChromosoneAtIndex(i));
		}
		return genesToReturn;
	}
	
	public ArrayList<Character> getGenesFromCrossoverPointToEnd(SimpleStringOrganism organism, int crossoverPoint)
	{
		ArrayList<Character> genesToReturn = new ArrayList<Character>(SimpleStringOrganism.getNumberOfChromosones() - crossoverPoint);
		for(int i = crossoverPoint; i < SimpleStringOrganism.getNumberOfChromosones(); i++)
		{
			genesToReturn.add(i-crossoverPoint, organism.getChromosoneAtIndex(i));
		}
		return genesToReturn;
	}
	
	public void mutateOrganism(Organism organism, float mutationRate)
	{
		if(mutationRate == 0) 
		{
			return;
		}
		int mutate = Math.abs(randomGenerator.nextInt())%((int)(1.0/mutationRate));
		if(mutate == 0)
		{
			organism.mutate();
		}
		
	}

}
